////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////

#include <SFML/Graphics.hpp>

#include "gameHeaders.h"

int main()
{
	// Create the main rendering window
	sf::RenderWindow App( sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT, 32), "Simple RPG v0.1", sf::Style::Fullscreen);
	App.ShowMouseCursor( false );
	App.SetBackgroundColor( sf::Color( 0, 0, 50 ) );
	//App.SetFramerateLimit( 0 );

	sf::Image BoarderImage;

	sf::Image TileBoarder;

	sf::Image CollisionBoarder;

	if( !BoarderImage.LoadFromFile( "boarder.png" ) )
	{
		return EXIT_FAILURE;
	}
	if( !TileBoarder.LoadFromFile( "tileBoarder.png" ) )
	{
		return EXIT_FAILURE;
	}
	if( !CollisionBoarder.LoadFromFile( "collisionBoarder.png" ) )
	{
		return EXIT_FAILURE;
	}

	sf::Sprite collisionBoarderSprite( CollisionBoarder );

	sf::Sprite TileBoarderSprite( TileBoarder );

	sf::Sprite BoarderSprite( BoarderImage );

	BoarderSprite.SetX( 0/*MAP_BOARDER_OFFSET*/ );
	BoarderSprite.SetY( 0/*MAP_BOARDER_OFFSET*/ );

	Map map( "testMap.txt" );
	vecDirFiles tileFiles( TILE_FOLDER );
	

	std::vector<sf::Image> CurrentPasteImage = loadAllTexture( tileFiles.getFileNames(), TILE_FOLDER );
	std::vector<sf::Image> tileImages = loadMapTextures( map.getMapTileImageNames(), map.getMapTileImageNames(), TILE_FOLDER );
	std::vector<sf::Sprite> CurrentPasteSprite;
	std::vector<std::string> CurrentImageNames = lineUpFileNames( tileFiles.getFileNames() );

	Palette pal( CurrentPasteImage, 28 * TILE_SIZE, 64 );
	//pal.input( App.GetInput() );
	for( unsigned int i = 0; i < CurrentPasteImage.size(); i++ )
	{
		sf::Sprite tmp;
		tmp.SetImage( CurrentPasteImage.at( i ) );
		CurrentPasteSprite.push_back( tmp );
	}

	sf::Sprite CurrentTile;

	float movementMod = SINGLE_DIRECTION_MOVEMENT_RATIO;
	bool keyUp = true;

	int setCollision = -1;
	int showCollisionGrid = -1;

	bool cKey = true;
	bool mKey = true;

	bool doubleKey = false;

	int cur_tile = 0;

	// h is used for testing the speed
	bool h = false;

	// Running is used to tell whether we are done with the game
	// or not.
	bool Running = true;

	int oldSize = (int)map.getMapTileImageNames().size();

	unsigned int tempNum;

	// Start game loop
	while (Running)
	{
		// Process events
		sf::Event Event;
		while (App.GetEvent(Event))
		{
			// Close window : exit
			if (Event.Type == sf::Event::Closed)
				Running = false;
		}

		///mouse input handled here.
		//move the current texture to the mouse's location
		//in itervals of 10s
		if( Event.Type == sf::Event::MouseMoved )
		{
			currentTile_X = Event.MouseMove.X / TILE_SIZE;
			currentTile_X *= TILE_SIZE;
			if( (unsigned)currentTile_X > WINDOW_WIDTH - CurrentPasteSprite[cur_tile].GetImage()->GetWidth() )
			{
				currentTile_X = WINDOW_WIDTH - (int)CurrentPasteSprite[cur_tile].GetImage()->GetWidth();
				std::cout << map.getMapTiles()[currentTile_X][currentTile_Y].getRect().Left << " " << map.getMapTiles()[currentTile_X][currentTile_Y].getRect().Top << std::endl;
			}
			currentTile_Y = Event.MouseMove.Y / TILE_SIZE;
			currentTile_Y *= TILE_SIZE;
			if( (unsigned)currentTile_Y > WINDOW_HEIGHT - CurrentPasteSprite[cur_tile].GetImage()->GetHeight() )
			{
				currentTile_Y = WINDOW_HEIGHT - (int)CurrentPasteSprite[cur_tile].GetImage()->GetHeight();
			}
		}

		//changes the current texture to be pasted
		if( Event.Type == sf::Event::MouseWheelMoved )
		{
			textureDelta = Event.MouseWheel.Delta;
			cur_tile += textureDelta;
			//check to see if we have looped through all the textures
			//if we have start over again.
			//i.e. textures[3] 0, 1, 2, 0, 1, 2, 0...
			if( cur_tile >= (int)map.getMapTileImageNames().size() )
			{
				int diff = cur_tile - (int)map.getMapTileImageNames().size();
				cur_tile = diff;
			}
			if( cur_tile < 0 )
			{
				int diff = (int)map.getMapTileImageNames().size() + cur_tile;
				cur_tile = diff;
			}
			textureDelta = 0;
			if( (unsigned)currentTile_X > WINDOW_WIDTH - CurrentPasteSprite[cur_tile].GetImage()->GetWidth() )
				currentTile_X = WINDOW_WIDTH - (int)CurrentPasteSprite[cur_tile].GetImage()->GetWidth();
			if( (unsigned)currentTile_Y > WINDOW_HEIGHT - CurrentPasteSprite[cur_tile].GetImage()->GetHeight() )
				currentTile_Y = WINDOW_HEIGHT - (int)CurrentPasteSprite[cur_tile].GetImage()->GetHeight();
		}
		if( Event.Type == sf::Event::MouseButtonPressed )
		{
			switch( Event.MouseButton.Button )
			{
			case sf::Mouse::Left:
				if( (App.GetInput().GetMouseX() > 0 && App.GetInput().GetMouseX() 
					< (unsigned int)( mapDrawWidth * TILE_SIZE ) ) && 
					(App.GetInput().GetMouseY() > 0 && App.GetInput().GetMouseY() 
					< (unsigned int)( mapDrawHeigth * TILE_SIZE ) ) )
				{
				
				oldSize = (int)map.getMapTileImageNames().size();
				tempNum = map.push_backMapTileImageName( CurrentImageNames[cur_tile] );
				map.getMapTiles()[currentTile_Y/TILE_SIZE][currentTile_X/TILE_SIZE].setNumber( tempNum );
				{
				std::string temp;
				temp += TILE_FOLDER;
				temp += "//";
				temp += map.getMapTileImageNames()[tempNum];
				if( oldSize < (int)map.getMapTileImageNames().size() )
				{
					sf::Image newImage;
					newImage.LoadFromFile( temp );
					tileImages.push_back( newImage );
				}
				map.getMapTiles()[currentTile_Y/TILE_SIZE][currentTile_X/TILE_SIZE].setImageNameAndLocation( temp );
				}
			
				if( setCollision == 1 )
				{
					map.getMapTiles()[currentTile_Y/TILE_SIZE][currentTile_X/TILE_SIZE].setCollision( true );
				}
				else
				{
					map.getMapTiles()[currentTile_Y/TILE_SIZE][currentTile_X/TILE_SIZE].setCollision( false );
				}
				}
				break;
			case sf::Mouse::Right:
				if( setCollision == 1 )
				{
					map.getMapTiles()[currentTile_Y/TILE_SIZE][currentTile_X/TILE_SIZE].setCollision( true );
				}
				else
				{
					map.getMapTiles()[currentTile_Y/TILE_SIZE][currentTile_X/TILE_SIZE].setCollision( false );
				}
				break;
			}
		}

		//changes the current tile to be placed opposite of the pageDown key.
		if( App.GetInput().IsKeyDown( sf::Key::PageUp ) && keyUp == false )
		{
			cur_tile++;
			if( cur_tile > (int)CurrentPasteSprite.size() - 1)
			{
				cur_tile = 0;
			}
			keyUp = true;
		}
		//changes the current tile to be placed opposite of pageUp key.
		if( App.GetInput().IsKeyDown( sf::Key::PageDown )  && keyUp == false )
		{
			cur_tile--;
			if( cur_tile < 0 )
			{
				cur_tile = (int)CurrentPasteSprite.size() - 1;
			}
			keyUp = true;
		}
		//changes to only one tile while pageUp and/or pageDown key is being pressed
		if( !App.GetInput().IsKeyDown( sf::Key::PageDown ) && !App.GetInput().IsKeyDown( sf::Key::PageUp ) )
		{
			keyUp = false;
		}
		if ( App.GetInput().IsKeyDown( sf::Key::Escape ) )
		{
			map.Save( "testMap.txt" );
			Running = false;
		}
		if( App.GetInput().IsKeyDown( sf::Key::C ) && cKey != false )
		{
			cKey = false;
			setCollision = -setCollision;
		}
		if( !App.GetInput().IsKeyDown( sf::Key::C ) )
		{
			cKey = true;
		}
		if( App.GetInput().IsKeyDown( sf::Key::M ) && mKey != false )
		{
			mKey = false;
			showCollisionGrid = -showCollisionGrid;
		}
		if( !App.GetInput().IsKeyDown( sf::Key::M ) )
		{
			mKey = true;
		}

		bool showCol;
		if( showCollisionGrid == 1 )
		{
			showCol = true;
		}
		else
		{
			showCol = false;
		}
		map.draw( App, showCol );
		//pal.draw( App );

		///handles the drawing portion of the program.
		// Display sprite in our window
		if( App.GetInput().GetMouseX() > 0/*MAP_BOARDER_OFFSET*/ && App.GetInput().GetMouseX() < (unsigned int)( mapDrawWidth * TILE_SIZE )
			&& App.GetInput().GetMouseY() > 0/*MAP_BOARDER_OFFSET*/ && App.GetInput().GetMouseY() < (unsigned int)( mapDrawHeigth * TILE_SIZE ) )
		{

			App.ShowMouseCursor( false );

			CurrentPasteSprite[cur_tile].SetX( (float)( 0/*MAP_BOARDER_OFFSET*/ + currentTile_X ) );
			CurrentPasteSprite[cur_tile].SetY( (float)( 0/*MAP_BOARDER_OFFSET*/ + currentTile_Y ) );
			App.Draw( CurrentPasteSprite[cur_tile] );

			if( setCollision == 1 )
			{
				collisionBoarderSprite.SetX( (float)( 0/*MAP_BOARDER_OFFSET*/ + currentTile_X ) );
				collisionBoarderSprite.SetY( (float)( 0/*MAP_BOARDER_OFFSET*/ + currentTile_Y ) );

				App.Draw( collisionBoarderSprite );
			}
			else
			{

				TileBoarderSprite.SetX( (float)( 0/*MAP_BOARDER_OFFSET*/ + currentTile_X ) );
				TileBoarderSprite.SetY( (float)( 0/*MAP_BOARDER_OFFSET*/ + currentTile_Y ) );

				App.Draw( TileBoarderSprite );
			}
		}
		else
		{
			App.ShowMouseCursor( true );
		}

		
		App.Draw( BoarderSprite );

		// Display window contents on screen
		App.Display();
	}

	return EXIT_SUCCESS;
}
